{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "0e6ee833-6c77-46c6-99fc-d1a4a8f998c5",
   "metadata": {},
   "source": [
    "# Working With Linear Systems in Python With `scipy.linalg`"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6ad522b7",
   "metadata": {},
   "source": [
    "## Getting Started With `scipy.linalg`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8771e87c",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "7cb1b8d8",
   "metadata": {},
   "source": [
    "## Working With Vectors and Matrices Using NumPy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "baca9a57",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7ed1bce7",
   "metadata": {},
   "outputs": [],
   "source": [
    "A = np.array([[1, 2], [3, 4], [5, 6]])\n",
    "A\n",
    "# Expected:\n",
    "# array([[1, 2],\n",
    "#        [3, 4],\n",
    "#        [5, 6]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d4b8e892",
   "metadata": {},
   "outputs": [],
   "source": [
    "A.dtype\n",
    "# Expected:\n",
    "# dtype('int64')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0cd7457b",
   "metadata": {},
   "outputs": [],
   "source": [
    "A = np.array([[1.0, 2], [3, 4], [5, 6]])\n",
    "A\n",
    "# Expected:\n",
    "# array([[1., 2.],\n",
    "#        [3., 4.],\n",
    "#        [5., 6.]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "90556517",
   "metadata": {},
   "outputs": [],
   "source": [
    "A.dtype\n",
    "# Expected:\n",
    "# dtype('float64')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3f25e5dc",
   "metadata": {},
   "outputs": [],
   "source": [
    "A.shape\n",
    "# Expected:\n",
    "# (3, 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9db6e09d",
   "metadata": {},
   "outputs": [],
   "source": [
    "A.T\n",
    "# Expected:\n",
    "# array([[1., 3., 5.],\n",
    "#        [2., 4., 6.]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5cbee03d",
   "metadata": {},
   "outputs": [],
   "source": [
    "v = np.array([1, 2, 3])\n",
    "v\n",
    "# Expected:\n",
    "# array([1, 2, 3])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f1bf3c1f",
   "metadata": {},
   "outputs": [],
   "source": [
    "v.shape\n",
    "# Expected:\n",
    "# (3,)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d23a234e",
   "metadata": {},
   "outputs": [],
   "source": [
    "v = np.array([[1, 2, 3]])\n",
    "v.shape\n",
    "# Expected:\n",
    "# (1, 3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "faa47683",
   "metadata": {},
   "outputs": [],
   "source": [
    "v = np.array([[1], [2], [3]])\n",
    "v.shape\n",
    "# Expected:\n",
    "# (3, 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9e01fad0",
   "metadata": {},
   "outputs": [],
   "source": [
    "v = np.array([1, 2, 3]).reshape(3, 1)\n",
    "v.shape\n",
    "# Expected:\n",
    "# (3, 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ab4e4752",
   "metadata": {},
   "outputs": [],
   "source": [
    "v = np.array([1, 2, 3]).reshape(-1, 1)\n",
    "v.shape\n",
    "# Expected:\n",
    "# (3, 1)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a7a0277c",
   "metadata": {},
   "source": [
    "### Using Convenience Functions to Create Arrays"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6ea69786",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "\n",
    "np.zeros((3, 2))\n",
    "# Expected:\n",
    "# array([[0., 0.],\n",
    "#        [0., 0.],\n",
    "#        [0., 0.]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ea0fd440",
   "metadata": {},
   "outputs": [],
   "source": [
    "np.ones((2, 3))\n",
    "# Expected:\n",
    "# array([[1., 1., 1.],\n",
    "#        [1., 1., 1.]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dfbf75d4",
   "metadata": {},
   "outputs": [],
   "source": [
    "np.random.rand(3, 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5bfa8e3b",
   "metadata": {},
   "outputs": [],
   "source": [
    "np.random.randn(3, 2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "475dfe8a",
   "metadata": {},
   "source": [
    "### Performing Operations on NumPy Arrays"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3257fef6",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "\n",
    "10 * np.ones((2, 2))\n",
    "# Expected:\n",
    "# array([[10., 10.],\n",
    "#        [10., 10.]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3ffedc13",
   "metadata": {},
   "outputs": [],
   "source": [
    "A = 10 * np.ones((2, 2))\n",
    "B = np.array([[2, 2], [5, 5]])\n",
    "A * B\n",
    "# Expected:\n",
    "# array([[20., 20.],\n",
    "#        [50., 50.]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e8f078f6",
   "metadata": {},
   "outputs": [],
   "source": [
    "A = np.array([[1, 2], [3, 4]])\n",
    "v = np.array([[5], [6]])\n",
    "A @ v\n",
    "# Expected:\n",
    "# array([[17],\n",
    "#        [39]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "afc2a7ad",
   "metadata": {},
   "outputs": [],
   "source": [
    "A = np.array([[1, 2], [3, 4]])\n",
    "v = np.array([[5], [6]])\n",
    "np.dot(A, v)\n",
    "# Expected:\n",
    "# array([[17],\n",
    "#        [39]])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a1419a2a",
   "metadata": {},
   "source": [
    "## Using `scipy.linalg.solve()` to Solve Linear Systems"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1006c500",
   "metadata": {},
   "source": [
    "### Using `scipy.linalg.solve()`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d5b45a92",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from scipy import linalg\n",
    "\n",
    "A = np.array(\n",
    "    [\n",
    "        [3, 2],\n",
    "        [2, -1],\n",
    "    ]\n",
    ")\n",
    "b = np.array([12, 1]).reshape((2, 1))\n",
    "x = linalg.solve(A, b)\n",
    "x\n",
    "# Expected:\n",
    "# array([[2.],\n",
    "#        [3.]])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4123510e",
   "metadata": {},
   "source": [
    "## Solving a Practical Problem: Building a Meal Plan"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "73bd50f7",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from scipy import linalg\n",
    "\n",
    "A = np.array(\n",
    "    [\n",
    "        [1, 9, 2, 1, 1],\n",
    "        [10, 1, 2, 1, 1],\n",
    "        [1, 0, 5, 1, 1],\n",
    "        [2, 1, 1, 2, 9],\n",
    "        [2, 1, 2, 13, 2],\n",
    "    ]\n",
    ")\n",
    "b = np.array([170, 180, 140, 180, 350]).reshape((5, 1))\n",
    "x = linalg.solve(A, b)\n",
    "x\n",
    "# Expected:\n",
    "# array([[10.],\n",
    "#        [10.],\n",
    "#        [20.],\n",
    "#        [20.],\n",
    "#        [10.]])"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language": "python",
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
